package persistence;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import model.Veiculo;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;

public class VeiculoDAO implements IDAO {

	private Session session;
	
	private Transaction transaction;
		
	private static VeiculoDAO instance;
	
	private VeiculoDAO() { }
	
	public static VeiculoDAO getInstance() {
		if (instance == null) {
			instance = new VeiculoDAO();
		}
		return instance;
	}
	
	
	public Veiculo getPorChavePrimaria(Object chavePrimaria) {
		session = HibernateSessionFactory.currentSession();
		transaction = session.beginTransaction();
		Veiculo veiculo = null;
		
		try{			
			veiculo = (Veiculo) session.get(Veiculo.class, (String) chavePrimaria);
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.closeSession();
		}				
		return veiculo;		
	}

	
	public Collection<Object> getTodos() {
		List<Object> veiculos = new ArrayList<Object>();
		session = HibernateSessionFactory.currentSession();
		transaction = session.beginTransaction();
		
		try {
			veiculos = session.createQuery("SELECT b FROM Veiculo AS b ORDER BY b.placa").list();
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {		
			HibernateSessionFactory.closeSession();
		}

		return veiculos;
	}

	
	public void remover(Object chavePrimaria) {
		session = HibernateSessionFactory.currentSession();
		transaction = session.beginTransaction();

		try {
			Veiculo veiculo = (Veiculo) session.get(Veiculo.class, (String) chavePrimaria);
			session.delete(veiculo);			
			transaction.commit();			
		} catch (Exception e) {			
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.closeSession();
		}		
	}

	
	public void salvar(Object veiculo) {
		session = HibernateSessionFactory.currentSession();
		transaction = session.beginTransaction();	
		
		try{
			session.save(veiculo);
			transaction.commit();			
		} catch (Exception e) {			
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.closeSession();
		}		
	}
	
	private boolean allEmpty(Veiculo v) {
		return isEmptyField(v.getPlaca()) && 
			   isEmptyField(v.getCategoria()) &&
			   isEmptyField(v.getAno()) &&
			   isEmptyField(v.getModelo()) &&
			   isEmptyField(v.getSituacao());		 
	}
	
	private boolean isEmptyField(String field) {
		return field == null || "".equals(field);
	}

	public Collection<Object> getVeiculosAccordingTo(Veiculo v) {
		Collection<Object> veiculos = null;
		session = HibernateSessionFactory.currentSession();
		transaction = session.beginTransaction();
		
		try {
			if (allEmpty(v)) {
				System.out.println("all empty");
				veiculos = getTodos();
				System.out.println(veiculos);
			} else {			
				Criteria c = session.createCriteria(Veiculo.class);
				if (v.getPlaca() != null) {
					c.add(Expression.like("placa", v.getPlaca()));
				} 
				if (v.getCategoria() != null) {
					c.add(Expression.like("categoria", v.getCategoria()));
				}
				if (v.getAno() != null) {
					c.add(Expression.like("ano", v.getAno()));
				}
				if (v.getModelo() != null) {
					c.add(Expression.like("modelo", v.getModelo()));
				}
				if (v.getSituacao() != null) {
					c.add(Expression.like("situacao", v.getSituacao()));
				}
				veiculos = c.list();
				transaction.commit();
			}			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.closeSession();
		}
		return veiculos;
	}
	
	public void alterar(Object objeto) {
		session = HibernateSessionFactory.currentSession();
		transaction = session.beginTransaction();
		try {
			Veiculo veiculoNew = (Veiculo) objeto;
			session.saveOrUpdate(veiculoNew);
			transaction.commit();						
		} catch (Exception e) {			
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}

}
